package com.mrd.util.service;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JSONObjectBuilder {

    private static <T> JSONObject objectToJsonObjectByConfig(T t, EntityFieldConfig config)
            throws Exception {
        JSONObject resultJsonObj = new JSONObject();

        if (null == t) {
            return resultJsonObj;
        }

        for (String key : config.getMembersMap().keySet()) {

            String tfname = key;

            String mName = "get" + tfname.substring(0, 1).toUpperCase() + tfname.substring(1);
            Method m = t.getClass().getMethod(mName, new Class[]{});
            Object resultObj = m.invoke(t, new Object[]{});
            if (null != resultObj) {
                if (config.getMembersMap().get(key) == EntityFieldType.Date) {
                    resultJsonObj.put(tfname, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) resultObj));
                } else if (config.getMembersMap().get(key) == EntityFieldType.Normal) {
                    resultJsonObj.put(tfname, resultObj);
                } else if (config.getMembersMap().get(key) == EntityFieldType.Entity) {
                    resultJsonObj.put(tfname, objectToJsonObjectByConfig(resultObj, config
                            .getMemberObjectsMap().get(key)));
                } else if (config.getMembersMap().get(key) == EntityFieldType.ListEntity) {
                    resultJsonObj.put(tfname, objectListToJsonArray((List<?>) resultObj, config
                            .getMemberObjectsMap().get(key)));
                }
            } else {
                resultJsonObj.put(tfname, "");
            }
        }

        return resultJsonObj;
    }

    private static <T> JSONArray objectListToJsonArray(List<T> objectList, EntityFieldConfig config)
            throws Exception {
        JSONArray resultArray = new JSONArray();

        if (null == objectList) {
            return resultArray;
        }

        // 先整理参数
        for (T t : objectList) {
            JSONObject o = objectToJsonObjectByConfig(t, config);
            resultArray.add(o);
        }

        return resultArray;
    }

    /**
     * @param stringConfig
     * @return
     */
    private static EntityFieldConfig initConfigByFormatString(String stringConfig) {
        EntityFieldConfig result = new EntityFieldConfig();
        String[] fields = stringConfig.split(",");

        Map<String, StringBuffer> memberObjectsConfigMap = new HashMap<String, StringBuffer>();

        for (String s : fields) {
            if (s.indexOf(".") == -1) {// 当前对象字段
                if (s.indexOf("|D") != -1) {
                    result.getMembersMap().put(s.replace("|D", ""), EntityFieldType.Date);
                } else if (s.indexOf("|L") != -1) {
                    result.getMembersMap().put(s.replace("|L", ""), EntityFieldType.ListEntity);
                } else {
                    result.getMembersMap().put(s, EntityFieldType.Normal);
                }
            } else {
                String mName = s.substring(0, s.indexOf("."));
                String fName = s.substring(s.indexOf(".") + 1);
                boolean isListEntity = false;
                if (mName.indexOf("|L") != -1) {
                    mName = mName.replace("|L", "");
                    isListEntity = true;
                }
                // System.out.println(s + "-->\t" + mName + "|" + fName);
                if (!memberObjectsConfigMap.containsKey(mName)
                        || memberObjectsConfigMap.get(mName) == null) {
                    StringBuffer configList = new StringBuffer();
                    configList.append(fName + ",");
                    memberObjectsConfigMap.put(mName, configList);
                    if (isListEntity) {
                        result.getMembersMap().put(mName, EntityFieldType.ListEntity);
                    } else {
                        result.getMembersMap().put(mName, EntityFieldType.Entity);
                    }

                } else {
                    memberObjectsConfigMap.get(mName).append(fName + ",");
                }
            }
        }

        for (String key : memberObjectsConfigMap.keySet()) {
            String tstringConfig = memberObjectsConfigMap.get(key).toString();
            tstringConfig = tstringConfig.substring(0, tstringConfig.length() - 1);
            // System.out.println(tstringConfig + "-------------");
            result.getMemberObjectsMap().put(key, initConfigByFormatString(tstringConfig));
        }

        return result;
    }

    /**
     * 通过配置字符串获取对象数组输出的json字符串
     *
     * @param configString 格式如下：field1,f2|D,f3.f1|D,f4.f1.f1,f5|L.f1 -----,|D表示Date类型,|L表示List对象
     */
    public static <T> JSONArray objectListToJsonArray(List<T> objectList, String configString)
            throws Exception {
        if (configString == null || configString.equals("")) {
            return null;
        }
        return objectListToJsonArray(objectList, initConfigByFormatString(configString));
    }

    /**
     * 通过配置字符串获取对象输出的json字符串
     *
     * @param configString 格式如下：field1,f2|D,f3.f1|D,f4.f1.f1,f5|L.f1 -----,|D表示Date类型,|L表示List对象
     */
    public static <T> JSONObject objectToJsonObjectByConfig(T t, String configString)
            throws Exception {
        if (configString == null || configString.equals("")) {
            return null;
        }
        return objectToJsonObjectByConfig(t, initConfigByFormatString(configString));
    }

    /**
     * 对象数组转为JSONArray的简易方法
     */
    public static <T> JSONArray objectListToJsonArray(List<T> objectList) throws Exception {
        JSONArray resultArray = new JSONArray();

        for (T t : objectList) {
            JSONObject o = JSONObject.fromObject(t);
            resultArray.add(o);
        }

        return resultArray;
    }

	/*
     * public static void main(String[] args) {
	 * try {
	 * List<Trail> objectList = new ArrayList<Trail>();
	 * Trail trail = new Trail();
	 * trail.setCONFIRM_TIME(new Date());
	 * Company customer = new Company();
	 * customer.setName("test");
	 * trail.setCustomer(customer);
	 * objectList.add(trail);
	 * JSONArray result;
	 * EntityFieldConfig config = new EntityFieldConfig();
	 * config.getMembersMap().put("CONFIRM_TIME", EntityFieldType.Date);
	 * config.getMembersMap().put("VALIDATE_TIME", EntityFieldType.Date);
	 * config.getMembersMap().put("id", EntityFieldType.Normal);
	 * config.getMembersMap().put("customer", EntityFieldType.Entity);
	 * EntityFieldConfig cusConfig = new EntityFieldConfig();
	 * cusConfig.getMembersMap().put("id", EntityFieldType.Normal);
	 * cusConfig.getMembersMap().put("name", EntityFieldType.Normal);
	 * config.getMemberObjectsMap().put("customer", cusConfig);
	 * result = JSONObjectBuilder.objectListToJsonArray(objectList, config);
	 * System.out.println(result);
	 * // new way
	 * String configString = "CONFIRM_TIME|D,VALIDATE_TIME|D,id,customer.id,customer.name";
	 * result = JSONObjectBuilder.objectListToJsonArray(objectList, configString);
	 * System.out.println(result);
	 * String dtoConfigString = "container.ct_type,goodsName,"
	 * +
	 * "goodAddresses|L.contacter.company,goodAddresses|L.contacter.address,goodAddresses|L.contacter.name,goodAddresses|L.contacter.phone,"
	 * + "goodAddresses|L.remark";
	 * List<TrailCTAddressDTO> ctAddressDTOList = new ArrayList<TrailCTAddressDTO>();
	 * TrailCTAddressDTO dto = new TrailCTAddressDTO();
	 * Container container = new Container();
	 * container.setCt_type("20HD");
	 * dto.setContainer(container);
	 * dto.setGoodsName("不锈钢");
	 * List<GoodAddress> goodAddresses = new ArrayList<GoodAddress>();
	 * GoodAddress e = new GoodAddress();
	 * e.setRemark("remark");
	 * Contacter gc = new Contacter();
	 * gc.setCompany("company");
	 * gc.setAddress("address");
	 * e.setContacter(gc);
	 * goodAddresses.add(e);
	 * dto.setGoodAddresses(goodAddresses);
	 * ctAddressDTOList.add(dto);
	 * result = objectListToJsonArray(ctAddressDTOList, dtoConfigString);
	 * System.out.println(result);
	 * String configString2 = "field1,f2|D,f3.f1|D,f4.f1.f1,f5|L.f1";
	 * EntityFieldConfig result2 = initConfigByFormatString(configString2);
	 * System.out.println(result2);
	 * } catch (Exception e) {
	 * e.printStackTrace();
	 * }
	 * }
	 */
}
